﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Data;
using System.Data.SqlClient;
using NUnit.Framework;
using System.Runtime.CompilerServices;
using System.Configuration;


namespace DBUtil
{
    public  class ADONet
    {
        /// <summary>
        /// 测试ado.net
        /// </summary>
        public void test()
        {
            //创建连接对象：    要告诉连接对象服务器地址、用户名、密码、要连接的数据库
            SqlConnection conn ;//中间用 ";"

            //using 可实现自动释放，只要执行完“{ }”中的代码，就会释放
            using (conn = new SqlConnection("server=.;uid = sa ;pwd =yubing1990;database=step2"))
            {
                conn.Open();//打开连接
                Console.WriteLine(conn.State);         //连接状态
                Console.WriteLine(conn.Database);       //正在连接的数据库
                Console.WriteLine(conn.ServerVersion);  //服务器版本
                Console.WriteLine(conn.ConnectionTimeout);//连接超时时间

                conn.Close();//关闭连接   数据库的连接数量是有限的，如果你只打开连接不关闭，那么有可能后面再开连接就无法连接到SqlServer服务器
                             //这里有个连接池的概念，连接池满了就不能再建立新的连接
                //其实在close的时候就已经释放了

                conn.Dispose();//释放连接资源

                

            }


            //C#7.0之后的写法
            {
                //此种写法将会在 conn1对象的作用域执行结束后释放conn1对象99
                using SqlConnection conn1 = new SqlConnection("server=.;uid=da;pwd=yubing1990;database=step2");
                conn.Open();//打开连接
                Console.WriteLine(conn.State);         //连接状态
                Console.WriteLine(conn.Database);       //正在连接的数据库
                Console.WriteLine(conn.ServerVersion);  //服务器版本
                Console.WriteLine(conn.ConnectionTimeout);//连接超时时间
            }
        }

        [Test]
        /// <summary>
        /// SqlCommand命令对象
        /// </summary>
        public void test2()
        {
            using SqlConnection conn = new SqlConnection("server=LY;uid=sa;pwd=yubing1990;database=step2");
            conn.Open();
            SqlCommand command = new SqlCommand("insert into Class vaules (1,'软件2班','计算机系')",conn); //设置连接对象，这条sql该在哪台服务器，哪个数据库里执行
            int aa= command.ExecuteNonQuery();//执行增、删、改，返回受影响行数

            int result=(int)command.ExecuteScalar();//获取sql语句结果的首行首列（就算查询结果是多行多列的，仍然只返回首行首列的数据）

        }

        /// <summary>
        /// SqlDataReader数据读取
        /// </summary>
        public void test3()
        { 
            //提供了从数据库提供只进的行流的方式。
            //在数据读取过程中需要一直保持与数据库的连接，适合数据量小的情况，执行效率还是可以的。
            //我们将SqlDataReader读取数据的模式称为“连接模式”
            using SqlConnection conn= new SqlConnection("server=LY;uid=sa;pwd=yubing1990;database=step2");
            conn.Open();
            SqlCommand command = new SqlCommand("select * from Class", conn);
            SqlDataReader reader = command.ExecuteReader();
            List<Class> list = new List<Class>();
           
            
            while (reader.Read())
            { 
                Class item = new Class();
                item.Id = (int)reader.GetValue(reader.GetOrdinal("Id"));
                item.Name = reader.GetValue(reader.GetOrdinal("Name")).ToString();
                item.College = reader.GetValue(reader.GetOrdinal("College")).ToString();
               
                list.Add(item);
            }//这段代码可以改进到下面

            while (reader.Read())
            {
                Class item1 = new Class(
                    reader.GetInt32(0),//这里获取的数据已经是Int类型，不需要手动强制转化，在程序员的层面不要拆箱
                    reader.GetString(1),
                    reader.GetString(2)
                );
                list.Add(item1);
            }


            //还可以这样写
            while (reader.Read())
            {
                Class item2 = new Class(
                    (int)reader["Id"],             //不需要获取字段下标，直接通过字段名称获取相应的值(需要手动拆箱)
                    reader["Name"].ToString(),
                    reader["College"].ToString()
                );
            }
        }

        [Test]
        /// <summary>
        ///DataAdapter 适配器模式读取数据
        /// </summary>
        public void testDataAdapter()
        {
            //此处并未手动打开连接
            SqlDataAdapter adapter = new SqlDataAdapter("select * from Class", new SqlConnection("server=YB;uid=sa;pwd=yubing1990;database=step2"));
            
            //读取数据
            DataSet dataSet = new DataSet();
            adapter.Fill(dataSet);//填充数据集
            Console.WriteLine(dataSet.Tables[0].Rows.Count);
        }


        [Test]
        //从配置文件中读取连接字符串
        public void getConnectionString()
        {
            string connStr=   ConfigurationManager.ConnectionStrings["connectionString"].ToString();
            using SqlConnection conn = new SqlConnection(connStr);
            using SqlDataAdapter sqlDataAdapter = new("select * from  Class", conn);
            DataTable dataTable= new DataTable();
            sqlDataAdapter.Fill(dataTable);

            Console.WriteLine(dataTable.Rows.Count);
        }

    }
    
    /// <summary>
    /// 班级类
    /// </summary>
    public class Class
    {
        public Class()
        { 
            
        }
        
        /// <summary>
        /// 构造函数有参重载
        /// </summary>
        /// <param name="id"></param>
        /// <param name="name"></param>
        /// <param name="college"></param>
        public Class(int id, string name, string college)
        {
            Id = id;
            Name = name;
            College = college;
        }

        public int Id { get; set; }

        public string Name { get; set; }

        public string College { get; set; }
    }
}
